#pragma once
//#include "stdafx.h"
#include "SpaceAgent.h"
#include "SpaceNode.h"
#include "CircleNode.h"
#include "Space.h"
namespace org
{
	namespace spark
	{
		namespace space
		{
			using org::spark::core::Agent;
			using org::spark::core::Observer;
			using org::spark::math::Vector;
			using org::spark::space::Space;
			//using org::spark::math::Vector4d;
org::spark::math::Vector *const SpaceAgent::BLACK = new org::spark::math::Vector(0, 0, 0);
org::spark::math::Vector *const SpaceAgent::WHITE = new org::spark::math::Vector(1.0, 1.0, 1.0);
org::spark::math::Vector *const SpaceAgent::BLUE = new org::spark::math::Vector(0, 0, 1.0);
org::spark::math::Vector *const SpaceAgent::GREEN = new org::spark::math::Vector(0, 1.0, 0);
org::spark::math::Vector *const SpaceAgent::RED = new org::spark::math::Vector(1.0, 0, 0);
org::spark::math::Vector *const SpaceAgent::CYAN = new org::spark::math::Vector(0.0, 1.0, 1.0);
org::spark::math::Vector *const SpaceAgent::YELLOW = new org::spark::math::Vector(1.0, 1.0, 0.0);
org::spark::math::Vector *const SpaceAgent::MAGENTA = new org::spark::math::Vector(1.0, 0.0, 1.0);
org::spark::math::Vector *const SpaceAgent::GREY = new org::spark::math::Vector(0.6, 0.6, 0.6);

			int SpaceAgent::getType()
			{
				return type;
			}

			SpaceAgent::SpaceAgent(Space *space, double r, int type)
			{
				InitializeInstanceFields();
				
					// Circle, dynamic, static nodes
					node = space->createCircleNode(r, this, type);
					this->type = type;
				
				
			}

			SpaceAgent::SpaceAgent(double r, int type)
			{
				InitializeInstanceFields();
			}

			SpaceAgent::SpaceAgent(double r)
			{
				InitializeInstanceFields();
			}

			SpaceAgent::SpaceAgent()
			{
				InitializeInstanceFields();
			}

			void SpaceAgent::jump(Vector *v)
			{
				node->jump(v);
			}

			void SpaceAgent::moveTo(Vector *v)
			{
				node->jump(v);
			}

			void SpaceAgent::move(Vector *v)
			{
				node->move(v);
			}

			void SpaceAgent::setRandomPosition()
			{
				node->setRandomPosition();
			}

			void SpaceAgent::die()
			{
				node->space->removeNode(node);
				// TODO: set it to null: look at all models and find incorrect behavior
				// because of the next line
				// Also be careful with parallel execution mode
						//		node = null;
				Agent::die();
			}

			void SpaceAgent::moveToSpace(Space *space, Vector *pos)
			{
				// If the agent's node is already removed,
				// then cannot move it to another space
				// TODO: correct it for parallel execution mode
				if (node->nodeIsRemoved)
					return;

				// TODO: move this code into Space class
				// in order to implement parallel execution mode
				if (space != 0 && space != node->space)
				{
					//Vector4d *color = node->color;
					double r = node->getRelativeSize();
					node->space->removeNode(node);

					switch (type)
					{/*
					case SQUARE2:
						node = space->createSquare2Node(r, this);
						break;
					case SQUARE:
						node = space->createSquareNode(r, this);
						break;
					*/
					case TORUS:
						node = space->createCircleNode(r, this, type);
						break;
					default:
						node = space->createCircleNode(r, this, type);
						break;
					}

					//node->color = color;
				}

				node->jump(pos);
			}

			double SpaceAgent::getRelativeSize()
			{
				return node->getRelativeSize();
			}

			org::spark::math::Vector *SpaceAgent::getPosition()
			{
				return node->getPosition();
			}

			SpaceNode *SpaceAgent::getNode()
			{
				return node;
			}

			org::spark::space::Space *SpaceAgent::getSpace()
			{
				return node->getSpace();
			}

			void SpaceAgent::setLabel(const std::string &label)
			{
				this->label = label;
			}

			std::string SpaceAgent::getLabel()
			{
				return label;
			}

			/*void SpaceAgent::setColor(Vector *c)
			{
				node->setColor(c);
			}*/

			/*void SpaceAgent::setColor(Vector4d *c)
			{
				node->setColor(c);
			}*/

			/*Vector4d *SpaceAgent::getColor()
			{
				return node->getColor();
			}*/
			/*
			org::spark::math::Vector *SpaceAgent::getRGBColor()
			{
				return node->getRGBColor();
			}*/
			/*
			void SpaceAgent::readObject(ObjectInputStream *ois) //throw(IOException, ClassNotFoundException)
			{
						//		System.out.println("Reading space agent");

				ois->defaultReadObject();

				// Restore the agent's node in the space.
				// Even when the serialization is not deep, the node for
				// the agent is associated with the space.
				// Because of this the external routine should take care
				// about removing such nodes
				// FIXME: in parallel SPARK we have only one space
				node->space = Observer::getDefaultSpace();
				node->space->addNode0(node);

				// FIXME: why do the state = 2 without this line?
				node->state = 0;
			}

			void SpaceAgent::writeObject(ObjectOutputStream *oos) //throw(IOException)
			{
						//		System.out.println("Writing space agent");

				oos->defaultWriteObject();

				// remove the agent's node from the space instantly
				// FIXME: synchronization issues
				// do serialization only in a serial way
				if (deepSerialization)
					node->space->removeNode0(node);
			}
			*/

			void SpaceAgent::InitializeInstanceFields()
			{
				type = CIRCLE;
			}
		}
	}
}
